<!--
 * @Descripttion: 
 * @LastEditors: xzh
 * @LastEditTime: 2023-11-08 20:08:26
-->
<template>
  <VxeTable ref="vxeTableRef" :key="tableParam.key">
    <template #vxeColumn>
      <slot name="preColumn" />
      <vxe-column
        v-for="(tableHead, index) in tableParam.tableHeadArr"
        :key="index"
        :field="tableHead.Name"
        :title="tableHead.Title"
        :width="tableHead.width || 150"
        :align="tableHead.align || 'center'"
        show-overflow="tooltip"
        show-header-overflow="tooltip"
        sortable
      >
        <template #default="scope">
          <!-- 格式化列信息 -->
          <TableFormatColumn :scope="scope" :tableHead="tableHead" />
        </template>
      </vxe-column>
      <slot name="lastColumn" />
    </template>
    <template #empty><slot name="empty" /></template>
  </VxeTable>
  <!-- 表格配置列按钮-evnCode不为空开启配置按钮 -->
  <TableCustomBtn
    v-if="!!propsParam.evnCode"
    class="table-customBtn"
    ref="tableCustomBtnRef"
  />
</template>

<script setup lang="ts">
import {
  ref,
  reactive,
  inject,
  watch,
  provide,
  nextTick,
  onMounted,
} from "vue";
import {
  paginationParam_Inf,
  pagination_Inf,
  propsParam_Inf,
} from "../index.type";
import { Table_Util } from "../util";
import type { object_Inf } from "@/utils/typings/index.type";
import Dile_Methods from "@/utils/methods";
import VxeTable from "../table-vxe/index.vue";
import TableCustomBtn from "./table-customBtn/index.vue";
import TableFormatColumn from "./table-formatColumn/index.vue";
/**
 * @Author: xzh
 * @Descripttion:表格传入参数
 * @Param:
 */
let propsParam = reactive<propsParam_Inf | object_Inf>(
  inject("propsParam") || {}
);

/**
 * @Author: xzh
 * @Descripttion:表格实例
 * @Param:
 */
let vxeTableRef = ref<any>(null);

/**
 * @Author: xzh
 * @Descripttion:表格配置按钮实例
 * @Param:
 */
let tableCustomBtnRef = ref<any>(null);

/**
 * @Author: xzh
 * @Descripttion:表格参数
 * @Param:
 */
let tableParam: object_Inf = {
  key: Dile_Methods.newGuid(),
  //默认表头:插槽+筛选完的固定表头
  tableHeadArr: Table_Util.getFixHeadArr(propsParam.tableHeadParam),
  isFormat: false, //是否在格式化
};
/**
 * @Author: xzh
 * @Descripttion:初始化渲染
 * @Param:
 */
onMounted(async () => {
  let { emitEvents } = propsParam;

  Object.assign(propsParam, {
    ...propsParam,
    emitEvents: {
      ...emitEvents,
      // resizableChange: hanldeResizableChange,
    },
  });
  await nextTick();
  //加载表格自定义按钮
  await initTableCustomBtn();
});

watch(
  () => propsParam.tableData,
  async () => {
    let { isFormat } = tableParam;
    //防止重复格式化
    !isFormat &&
      (propsParam.tableData || []).length > 0 &&
      (await formatTableData());
  },
  { deep: true }
);

/**
 * @Author: xzh
 * @Descripttion:监听表格数据变化
 * @Param:
 */
let formatTableData = async () => {
  try {
    propsParam.loading = true;
    let { tableData, tableHeadParam, tableRecords } = propsParam,
      { pagination, activePage } = paginationParam;
    // //格式化表格数据
    // tableData = tableData.map((x: object_Inf) =>
    //   Table_Util.formatClassPermissions(x)
    // );
    // //格式化表头信息
    let tableHeadArr = Table_Util.formatTableHeadArr(tableData, tableHeadParam);
    Object.assign(tableParam, {
      key: Dile_Methods.newGuid(),
      tableHeadArr,
      isFormat: true,
    });
    propsParam.tableData = tableData;
    //修改分页参数
    Object.assign(paginationParam, {
      pagination: {
        ...pagination,
        page: activePage,
        records: tableRecords,
      },
      //加载完表格重置活动页
      activePage: 1,
    });
    //渲染完后退出格式化状态-防止监听重复加载
    await nextTick();
    //加载表格自定义按钮
    await initTableCustomBtn();
    tableParam.isFormat = false;
  } finally {
    propsParam.loading = false;
  }
};

/**
 * @Author: xzh
 * @Descripttion:加载表格自定义按钮
 * @Param:
 */
let initTableCustomBtn = async () => {
  let { tableRef } = vxeTableRef.value,
    { evnCode } = propsParam;
  //加载表格配置按钮
  !!evnCode && (await tableCustomBtnRef.value.initTableCustomBtn(tableRef));
};

/**
 * @Author: xzh
 * @Descripttion:宽拖动发生变化事件
 * @Param:
 * @param {*} event
 */
let hanldeResizableChange = (event: object_Inf) => {
  let { column, resizeWidth } = event;
  //修改缓存列信息
  tableCustomBtnRef.value.handleColumnInfoChange({
    ...column,
    width: resizeWidth,
  });
  //保存用户配置信息
  tableCustomBtnRef.value.handleSaveUserEvn();
};
/**
 * @Author: xzh
 * @Descripttion:分页切换事件
 * @Param:
 * @param {*} event
 */
let handlePageChange = (event: object_Inf) => {
  let { refreshTable = () => {} } = propsParam.emitEvents || {},
    { page } = paginationParam.pagination;
  //记录当前活动页
  paginationParam.activePage = page;
  refreshTable();
};

/**
 * @Author: xzh
 * @Descripttion:获取当前分页参数
 * @Param:
 * @param {*} pagination_Inf
 */
let getPagination = (): pagination_Inf => {
  let { pagination } = paginationParam;
  //记录当前活动页
  paginationParam.activePage = pagination.page;
  return pagination;
};

/**
 * @Author: xzh
 * @Descripttion: 重置分页
 * @Param:
 */
let resetPagination = () => {
  let { pagination } = paginationParam;
  Object.assign(paginationParam, {
    pagination: {
      ...pagination,
      page: 1,
    },
    activePage: 1,
  });
};

/**
 * @Author: xzh
 * @Descripttion: 获取选中行
 * @Param:
 */
let getSelectedRow = () => {
  let { getCheckboxRecords = () => {}, getRadioRecord = () => {} } =
      vxeTableRef.value.tableRef,
    { checkbox } = propsParam;
  return !!checkbox
    ? getCheckboxRecords(false)
    : [getRadioRecord()].filter(
        (x: object_Inf) => Object.keys(x || {}).length > 0
      );
};

/**
 * @Author: xzh
 * @Descripttion:分页参数
 * @Param:
 */
let paginationParam: paginationParam_Inf = {
  pagination: Table_Util.defaultPagination,
  activePage: 1,
  pageChange: handlePageChange,
};
provide("paginationParam", paginationParam);

//暴露数据或方法
defineExpose({
  //获取当前分页参数
  getPagination,
  //重置分页
  resetPagination,
  //获取vxe表格实例
  getVxeTableRef: () => vxeTableRef.value.tableRef,
  //获取选中行
  getSelectedRow,
  //设置行选中
  setCheckboxRow: (dataArr: Array<object_Inf>, isSelected: boolean) =>
    vxeTableRef.value.setCheckboxRow(dataArr, isSelected), //设置行选中
  //清除行选中
  clearCheckboxRow: () => vxeTableRef.value.clearCheckboxRow(),
});
</script>
<style lang="scss" scoped></style>
